﻿using UnityEngine;
using System;
using System.Timers;
using System.Text;
using com.gzc.ThreadLockEvent;

namespace SocialPoint.Examples.MVC {

    /// <summary>
    /// 游戏计数器
    /// </summary>
    public class TimerModel {

        private Timer m_timerClock = null;

        private int m_clockTime = 0;
        /// <summary>
        /// 游戏计时（单位：秒）
        /// </summary>
        public int ClockTime {
            get {
                return m_clockTime;
            }
            private set {
                m_clockTime = value;
            }
        }

        private int m_gameTime = 0;
        /// <summary>
        /// 游戏时长（单位：秒）
        /// </summary>
        public int GameTime {
            get {
                return m_gameTime;
            }
            private set {
                m_gameTime = value;
            }
        }

        private readonly string STR_GAME_TIME_LEN = null;
        private string m_gameClockTimeText;

        public string GameClockTimeText {
            get {
                return m_gameClockTimeText;
            }
            private set {
                m_gameClockTimeText = value;
            }
        }

        #region 构造函数

        public TimerModel (double timerMillisecondInterval, string gameTimeLen) {
            STR_GAME_TIME_LEN = gameTimeLen;
            InitTimer(timerMillisecondInterval, STR_GAME_TIME_LEN);
        }

        public TimerModel ( ) {
            STR_GAME_TIME_LEN = "15:00";
            InitTimer(1000D, STR_GAME_TIME_LEN);
        }

        #endregion 构造函数

        private void OnTimer (object sender, ElapsedEventArgs e) {
            try {
                this.m_clockTime++;
                int countdown = this.m_gameTime - this.m_clockTime;
                if (this.m_gameTime != 0) {
                    this.m_gameClockTimeText = this.SecondsToTime(countdown);
                }

                this.UpdateTimer( );

                // 时间到了
                if (this.m_clockTime == this.m_gameTime) {
                    this.TimeOver( );      
                }
            } catch (Exception ex) {
                Debug.LogError("OnTimer( ) Exception: " + ex.Message + " StackTrace=" + ex.StackTrace);
            }
        }

        private void InputToSeconds (string timerInput) {
            try {
                string[ ] timeArray = new string[2];
                int minutes = 0;
                int seconds = 0;
                int occurence = 0;
                int length = 0;

                occurence = timerInput.LastIndexOf(":");
                length = timerInput.Length;

                //Check for invalid input
                if (occurence == -1 || length != 5) {
                    Debuger.LogError("Invalid Time Format.");
                    ResetTimer( );
                } else {
                    timeArray = timerInput.Split(':');

                    seconds = Convert.ToInt32(timeArray[1]);
                    minutes = Convert.ToInt32(timeArray[0]);

                    this.m_gameTime += seconds;
                    this.m_gameTime += minutes * 60;
                    //Debuger.Log(string.Format("gameTime={0}", m_gameTime));
                }
            } catch (Exception e) {
                Debuger.LogError("inputToSeconds(): " + e.Message + " StackTrace=" + e.StackTrace);
            }
        }

        private const string STR_NUM_ZERO = "0";
        private const string STR_SYMBOL_COLON = ":";
        private StringBuilder m_stringBuilder = new StringBuilder( );

        private string SecondsToTime (int seconds) {
            int minutes = 0;

            while (seconds >= 60) {
                minutes += 1;
                seconds -= 60;
            }
            while (minutes >= 60) {
                minutes -= 60;
            }

            m_stringBuilder.Remove(0, m_stringBuilder.Length);
            string strMinutes = minutes.ToString( );
            string strSeconds = seconds.ToString( );     

            if (strMinutes.Length < 2) {              
                m_stringBuilder.Append(STR_NUM_ZERO);
                m_stringBuilder.Append(strMinutes);
            } else {
                m_stringBuilder.Append(strMinutes);
            }

            m_stringBuilder.Append(STR_SYMBOL_COLON);

            if (strSeconds.Length < 2) {            
                m_stringBuilder.Append(STR_NUM_ZERO);
                m_stringBuilder.Append(strSeconds);
            } else {
                m_stringBuilder.Append(strSeconds);
            }
          
            return m_stringBuilder.ToString( );   
        }

        void InitTimer (double timerMillisecondInterval, string gameTimeLen) {
            m_timerClock = new Timer( );
            // 为Timer.Elapsed 事件设置一个事件处理程序
            m_timerClock.Elapsed += new ElapsedEventHandler(OnTimer);
            // 间隔多少毫秒
            m_timerClock.Interval = timerMillisecondInterval;

            InitValue( );
            InputToSeconds(gameTimeLen);
        }

        void InitValue ( ) {
            this.m_clockTime = 0;
            this.GameTime = 0;
            m_gameClockTimeText = STR_GAME_TIME_LEN;
        }        

        public event Action StartTimerEvent;
        public event Action PauseTimerEvent;
        public event Action ResetTimerEvent;
        public event Action StopTimerEvent;

        public void StartTimer ( ) {
            m_timerClock.Start( );

            OnStartTimerEvent( );
        }

        protected virtual void OnStartTimerEvent ( ) {
            if (null != StartTimerEvent) {
                StartTimerEvent( );
            }
        }

        public void StopTimer ( ) {
            m_timerClock.Stop( );

            OnStopTimerEvent( );
        }

        protected virtual void OnStopTimerEvent ( ) {
            if (null != StopTimerEvent) {
                StopTimerEvent( );
            }
        }

        public void PauseTimer ( ) {
            this.m_timerClock.Stop( );

            OnPauseTimerEvent( );
        }

        protected virtual void OnPauseTimerEvent ( ) {
            if (null != PauseTimerEvent) {
                PauseTimerEvent( );
            }
        }

        public void ResetTimer ( ) {
            InitValue( );
            InputToSeconds(STR_GAME_TIME_LEN);

            OnResetTimerEvent( );
        }

        protected virtual void OnResetTimerEvent ( ) {
            if (null != ResetTimerEvent) {
                ResetTimerEvent( );
            }
        }

        UpdateTimerViewEvent m_updateTimerViewEvent = new UpdateTimerViewEvent( );
        private void UpdateTimer ( ) {
            m_updateTimerViewEvent.timerText = this.m_gameClockTimeText;
            EventDispatcher.Instance( ).DispatchEvent(UpdateTimerViewEvent.UPDATE_TIMER_VIEW_EVENT, m_updateTimerViewEvent);
        }

        void TimeOver ( ) {
            Debug.Log("Time over");              
        }

    }
}
